"""
Excel导出功能模块
支持Excel、CSV、JSON格式的数据导出
"""
import pandas as pd
import json
import uuid
import hashlib
import os
from typing import List, Dict, Any, Optional
from datetime import datetime, timedelta
from pathlib import Path
import logging

from .models import ExportRequest, ExportRecordOut, ExportType, ExportStatus

logger = logging.getLogger(__name__)


class ExcelExportService:
    """Excel导出服务"""
    
    def __init__(self, export_dir: str = "exports"):
        self.export_dir = Path(export_dir)
        self.export_dir.mkdir(exist_ok=True)
        self.max_records = 100000  # 最大导出记录数
        self.file_retention_days = 30  # 文件保留天数
    
    def export_signal_data(self, 
                          signal_data: List[Dict[str, Any]], 
                          export_request: ExportRequest,
                          user_id: str,
                          team_id: str) -> ExportRecordOut:
        """导出信号数据"""
        try:
            # 验证数据量
            if len(signal_data) > self.max_records:
                raise ValueError(f"数据量超过限制，最大支持{self.max_records}条记录")
            
            # 生成导出记录
            export_id = str(uuid.uuid4())
            timestamp = datetime.utcnow().strftime("%Y%m%d_%H%M%S")
            
            # 根据导出类型生成文件名
            if export_request.export_type == ExportType.EXCEL:
                file_name = f"signal_data_{timestamp}.xlsx"
                file_path = self._export_to_excel(signal_data, export_request, file_name)
            elif export_request.export_type == ExportType.CSV:
                file_name = f"signal_data_{timestamp}.csv"
                file_path = self._export_to_csv(signal_data, export_request, file_name)
            elif export_request.export_type == ExportType.JSON:
                file_name = f"signal_data_{timestamp}.json"
                file_path = self._export_to_json(signal_data, export_request, file_name)
            else:
                raise ValueError(f"不支持的导出类型: {export_request.export_type}")
            
            # 计算文件信息
            file_size = os.path.getsize(file_path)
            checksum = self._calculate_checksum(file_path)
            
            # 创建导出记录
            export_record = ExportRecordOut(
                export_id=export_id,
                user_id=user_id,
                team_id=team_id,
                export_type=export_request.export_type,
                file_name=file_name,
                file_path=str(file_path),
                file_size=file_size,
                filter_criteria=export_request.filter_criteria,
                record_count=len(signal_data),
                checksum=checksum,
                status=ExportStatus.COMPLETED,
                created_at=datetime.utcnow(),
                completed_at=datetime.utcnow(),
                expires_at=datetime.utcnow() + timedelta(days=self.file_retention_days)
            )
            
            logger.info(f"导出完成: {file_name}, 记录数: {len(signal_data)}")
            return export_record
            
        except Exception as e:
            logger.error(f"导出失败: {str(e)}")
            # 返回失败的导出记录
            return ExportRecordOut(
                export_id=str(uuid.uuid4()),
                user_id=user_id,
                team_id=team_id,
                export_type=export_request.export_type,
                file_name="",
                file_path="",
                file_size=0,
                filter_criteria=export_request.filter_criteria,
                record_count=0,
                checksum="",
                status=ExportStatus.FAILED,
                created_at=datetime.utcnow(),
                completed_at=None,
                expires_at=None
            )
    
    def _export_to_excel(self, 
                        signal_data: List[Dict[str, Any]], 
                        export_request: ExportRequest,
                        file_name: str) -> str:
        """导出为Excel格式"""
        file_path = self.export_dir / file_name
        
        # 创建Excel写入器
        with pd.ExcelWriter(file_path, engine='openpyxl') as writer:
            # Sheet1: 信号数据
            df_signals = pd.DataFrame(signal_data)
            df_signals.to_excel(writer, sheet_name='信号数据', index=False)
            
            # Sheet2: 数据统计
            stats_data = self._generate_statistics(signal_data)
            df_stats = pd.DataFrame([stats_data])
            df_stats.to_excel(writer, sheet_name='数据统计', index=False)
            
            # Sheet3: 导出信息
            export_info = {
                '导出时间': datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S'),
                '导出类型': export_request.export_type.value,
                '记录数量': len(signal_data),
                '筛选条件': json.dumps(export_request.filter_criteria, ensure_ascii=False),
                '文件格式': export_request.file_format,
                '包含附件': export_request.include_attachments
            }
            df_info = pd.DataFrame([export_info])
            df_info.to_excel(writer, sheet_name='导出信息', index=False)
            
            # 如果有任务数据，添加任务Sheet
            if export_request.filter_criteria.get('include_tasks', False):
                tasks_data = self._get_related_tasks(signal_data)
                if tasks_data:
                    df_tasks = pd.DataFrame(tasks_data)
                    df_tasks.to_excel(writer, sheet_name='相关任务', index=False)
        
        return str(file_path)
    
    def _export_to_csv(self, 
                      signal_data: List[Dict[str, Any]], 
                      export_request: ExportRequest,
                      file_name: str) -> str:
        """导出为CSV格式"""
        file_path = self.export_dir / file_name
        
        # 转换为DataFrame并导出
        df = pd.DataFrame(signal_data)
        df.to_csv(file_path, index=False, encoding='utf-8-sig')
        
        return str(file_path)
    
    def _export_to_json(self, 
                       signal_data: List[Dict[str, Any]], 
                       export_request: ExportRequest,
                       file_name: str) -> str:
        """导出为JSON格式"""
        file_path = self.export_dir / file_name
        
        # 构建导出数据结构
        export_data = {
            'metadata': {
                'export_time': datetime.utcnow().isoformat(),
                'export_type': export_request.export_type.value,
                'record_count': len(signal_data),
                'filter_criteria': export_request.filter_criteria,
                'file_format': export_request.file_format,
                'include_attachments': export_request.include_attachments
            },
            'statistics': self._generate_statistics(signal_data),
            'data': signal_data
        }
        
        # 如果有任务数据，添加任务信息
        if export_request.filter_criteria.get('include_tasks', False):
            export_data['tasks'] = self._get_related_tasks(signal_data)
        
        # 写入JSON文件
        with open(file_path, 'w', encoding='utf-8') as f:
            json.dump(export_data, f, ensure_ascii=False, indent=2, default=str)
        
        return str(file_path)
    
    def _generate_statistics(self, signal_data: List[Dict[str, Any]]) -> Dict[str, Any]:
        """生成数据统计信息"""
        if not signal_data:
            return {}
        
        # 提取信号强度数据
        signal_strengths = [record.get('signal_strength', -120) for record in signal_data]
        
        # 计算统计指标
        stats = {
            '总记录数': len(signal_data),
            '平均信号强度': round(sum(signal_strengths) / len(signal_strengths), 2),
            '最强信号': max(signal_strengths),
            '最弱信号': min(signal_strengths),
            '信号范围': max(signal_strengths) - min(signal_strengths),
            '数据时间范围': self._get_time_range(signal_data),
            '设备数量': len(set(record.get('device_id', '') for record in signal_data)),
            '网络类型分布': self._get_network_type_distribution(signal_data),
            '运营商分布': self._get_operator_distribution(signal_data)
        }
        
        return stats
    
    def _get_time_range(self, signal_data: List[Dict[str, Any]]) -> str:
        """获取数据时间范围"""
        if not signal_data:
            return "无数据"
        
        timestamps = []
        for record in signal_data:
            collected_at = record.get('collected_at')
            if collected_at:
                if isinstance(collected_at, str):
                    timestamps.append(datetime.fromisoformat(collected_at.replace('Z', '+00:00')))
                elif isinstance(collected_at, datetime):
                    timestamps.append(collected_at)
        
        if not timestamps:
            return "无时间数据"
        
        min_time = min(timestamps)
        max_time = max(timestamps)
        return f"{min_time.strftime('%Y-%m-%d %H:%M:%S')} 至 {max_time.strftime('%Y-%m-%d %H:%M:%S')}"
    
    def _get_network_type_distribution(self, signal_data: List[Dict[str, Any]]) -> Dict[str, int]:
        """获取网络类型分布"""
        network_types = {}
        for record in signal_data:
            network_type = record.get('network_type', '未知')
            network_types[network_type] = network_types.get(network_type, 0) + 1
        return network_types
    
    def _get_operator_distribution(self, signal_data: List[Dict[str, Any]]) -> Dict[str, int]:
        """获取运营商分布"""
        operators = {}
        for record in signal_data:
            operator = record.get('operator_name', '未知')
            operators[operator] = operators.get(operator, 0) + 1
        return operators
    
    def _get_related_tasks(self, signal_data: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """获取相关任务数据（模拟实现）"""
        # 这里应该从数据库查询相关任务
        # 暂时返回空列表
        return []
    
    def _calculate_checksum(self, file_path: str) -> str:
        """计算文件SHA256校验和"""
        sha256_hash = hashlib.sha256()
        with open(file_path, "rb") as f:
            for byte_block in iter(lambda: f.read(4096), b""):
                sha256_hash.update(byte_block)
        return sha256_hash.hexdigest()
    
    def cleanup_expired_files(self) -> int:
        """清理过期文件"""
        cleaned_count = 0
        current_time = datetime.utcnow()
        
        for file_path in self.export_dir.iterdir():
            if file_path.is_file():
                # 检查文件是否过期
                file_age = current_time - datetime.fromtimestamp(file_path.stat().st_mtime)
                if file_age.days > self.file_retention_days:
                    try:
                        file_path.unlink()
                        cleaned_count += 1
                        logger.info(f"删除过期文件: {file_path}")
                    except Exception as e:
                        logger.error(f"删除文件失败: {file_path}, 错误: {str(e)}")
        
        return cleaned_count
    
    def get_export_history(self, user_id: str, team_id: str, limit: int = 100) -> List[ExportRecordOut]:
        """获取导出历史（模拟实现）"""
        # 这里应该从数据库查询导出历史
        # 暂时返回空列表
        return []
    
    def download_export_file(self, export_id: str, user_id: str) -> Optional[str]:
        """下载导出文件"""
        # 这里应该从数据库查询导出记录，验证权限，返回文件路径
        # 暂时返回None
        return None


class ExportService:
    """导出服务主类"""
    
    def __init__(self, export_dir: str = "exports"):
        self.excel_service = ExcelExportService(export_dir)
    
    def export_data(self, 
                   data: List[Dict[str, Any]], 
                   export_request: ExportRequest,
                   user_id: str,
                   team_id: str) -> ExportRecordOut:
        """导出数据"""
        return self.excel_service.export_signal_data(data, export_request, user_id, team_id)
    
    def cleanup_expired_files(self) -> int:
        """清理过期文件"""
        return self.excel_service.cleanup_expired_files()
    
    def get_export_history(self, user_id: str, team_id: str, limit: int = 100) -> List[ExportRecordOut]:
        """获取导出历史"""
        return self.excel_service.get_export_history(user_id, team_id, limit)
    
    def download_export_file(self, export_id: str, user_id: str) -> Optional[str]:
        """下载导出文件"""
        return self.excel_service.download_export_file(export_id, user_id)